package com.xzc.util;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.digest.MD5;
import cn.hutool.http.HttpUtil;
import com.xzc.Constants;
import com.xzc.pojo.Project;
import com.xzc.pojo.ZenTaoValues;
import com.xzc.pojo.response.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 熊志聪
 * @Classname ZenTaoUtil
 * @Description 禅道工具类
 * @Date 2021/12/12 21:46
 */
@Slf4j
public class ZenTaoUtils {
    public static void main(String[] args) {
        ZenTaoValues zenTaoValues = ReadValues.getZenTaoValues();
//        List<Project> allProjects = getAllProjects(zenTaoValues);
//        Map<Integer, Project> projectMap = allProjects.stream().collect(Collectors.toMap
//                (Project::getId, Function.identity()));
//        Map<String, Project> projectCodeMap = allProjects.stream().collect(Collectors.toMap
//                (Project::getCode, Function.identity()));
//        List<User> usersByDept = ZenTaoUtils.getUsersByDept(zenTaoValues);
//        log.info("获取本部门成员结束...");
//        Map<String, User> userMap = usersByDept.stream().collect(Collectors.toMap
//                (User::getAccount, Function.identity()));
//        getTask("45100",zenTaoValues);
//        Collection<Task> tasksByProjectId = ZenTaoUtils.getTasksByProjectId(195, zenTaoValues);
//        Collection<Bug> bugs = ZenTaoUtils.getBugs(62, zenTaoValues, projectMap,projectCodeMap,userMap);

//        System.out.println(tasksByProjectId.size());
//        for(Task task:tasksByProjectId){
//            if("42877".equals(task.getId())) {
//                System.out.println(task);
//            }
//        }
        writeResponseData();
    }
    public static void writeResponseData(){
        String response= FileUtil.readString(System.getProperty("user.dir")+"\\"+"1.txt",StandardCharsets.UTF_8);
        ZenTaoResponse zenTaoResponse = JsonUtils.jsonToBean(response, ZenTaoResponse.class);
        FileUtil.writeString(zenTaoResponse.getData(),System.getProperty("user.dir")+"\\"+"2.txt",StandardCharsets.UTF_8);
    }
    public static Collection<Bug> getBugs(Integer projectId, ZenTaoValues zenTaoValues,Map<Integer, Project> projectMap,Map<String, Project> projectCodeMap,Map<String, User> userMap){
        Collection<Bug> bugsByProjectId = getBugsByProjectId(projectId, zenTaoValues);
        Iterator<Bug> iterator = bugsByProjectId.iterator();
        while (iterator.hasNext()){
            Bug next = iterator.next();
//            if(next.getId().equals(36727)){
//                log.info("bug:{}",next);
//            }
            getBugWorkTime(next,zenTaoValues);
            //非本部门的成员或者无用户
            if(StringUtils.isBlank(next.getUserName())||userMap.get(next.getUserName())==null){
                iterator.remove();
            }else {
                getBugToStoryProject(next,zenTaoValues,projectMap,projectCodeMap);
            }
        }
//        System.out.println(bugsByProjectId.size());
        return bugsByProjectId;
    }
    public static Set<String> getTeamMember(Integer projectId, ZenTaoValues zenTaoValues){
        Set<String> members=new HashSet<>();
        //project-team-195.json
        String apiURL = Constants.URL_PREFIX + "project-team-"+projectId+".json?" + zenTaoValues.getZenTaoSuffix();
        String apiResult = HttpUtil.get(apiURL);
        ZenTaoResponse zenTaoResponse = JsonUtils.jsonToBean(apiResult, ZenTaoResponse.class);
        if (zenTaoResponse!=null&&compareZenTaoResponse(zenTaoResponse)) {
            return JsonUtils.jsonToBean(zenTaoResponse.getData(), TeamMemberResponse.class).getTeamMembers().values().stream().map(Member::getAccount).collect(Collectors.toSet());
        }
        return members;
    }

    private static void getBugWorkTime(Bug bug,ZenTaoValues zenTaoValues){
        //bug-view-36787.html bug-ajaxGetDetail-[bugID].json
        String apiURL = Constants.URL_PREFIX + "bug-ajaxGetDetail-"+bug.getId()+".json?" + zenTaoValues.getZenTaoSuffix();
        String apiResult = HttpUtil.get(apiURL);
        ZenTaoResponse zenTaoResponse = JsonUtils.jsonToBean(apiResult, ZenTaoResponse.class);
        if (zenTaoResponse!=null&&compareZenTaoResponse(zenTaoResponse)) {
            Collection<Action> actions = JsonUtils.jsonToBean(zenTaoResponse.getData(), ActionResponse.class).getActions().values();
            if(CollUtil.isEmpty(actions)){
                return ;
            }
            for(Action action:actions){
                if("resolved".equals(action.getAction())||"commented".equals(action.getAction())){
                    bug.setUserName(action.getActor());
                    String[] split = action.getComment().split("<p>");
                    if(split.length>0){
                        for(String comment:split){
                            if(comment.contains("工时:")){

                                bug.setWorkTime(new BigDecimal(getNumberByComment(comment)));
                            }
                        }
                    }
                    if(bug.getWorkTime().compareTo(BigDecimal.ZERO)>0){
                        break;
                    }

                }
            }
        }
    }
    private static String getNumberByComment(String comment){
        int startIndex=comment.indexOf("工时:")+3;
        StringBuilder stringBuilder=new StringBuilder();
        for(char c:comment.substring(startIndex).toCharArray()){
            String c1=String.valueOf(c);
            if(c1.matches("[0-9]")|| ".".equals(c1)){
                stringBuilder.append(c);
            }
        }
        return stringBuilder.toString();
    }
    private static void getBugToStoryProject(Bug bug,ZenTaoValues zenTaoValues,Map<Integer, Project> projectMap,Map<String, Project> projectCodeMap){
        //获取bug所对应的需求的项目,当需求不存在的情况下获取当前bug所在的项目
        String projectCodeByStoryId ="";
        try {
            projectCodeByStoryId=getProjectCodeByStoryId(null, bug, zenTaoValues, projectMap);
        }catch (RuntimeException e){
            bug.setProjectCode(projectMap.get(Integer.valueOf(bug.getProject())).getCode());
        }
        if(StringUtils.isNotBlank(projectCodeByStoryId)){
            bug.setProjectCode(projectCodeByStoryId);
            bug.setProject(projectCodeMap.get(projectCodeByStoryId).getId());
        }
    }
    public static String getProjectCodeByStoryId(Task task,Bug bug,ZenTaoValues zenTaoValues,Map<Integer, Project> projectMap){
        String storyId=(task!=null)?task.getStoryID(): bug.getStory();
        if(StringUtils.isBlank(storyId)){
            if(task!=null&&task.getProject()!=null){
                return projectMap.get(task.getProject()).getCode();
            }
            if(bug!=null&&bug.getProject()!=null){
                return projectMap.get(bug.getProject()).getCode();
            }
            return zenTaoValues.getNoStoryProjectCode();
        }
        //zentao/story-view-33224.html
        String apiURL = Constants.URL_PREFIX + "story-view-"+storyId+".json?" + zenTaoValues.getZenTaoSuffix();
        String apiResult = HttpUtil.get(apiURL);
        if(apiResult.contains("alert")){
            throw new RuntimeException("获取任务对应需求的项目信息失败!");
        }
        ZenTaoResponse zenTaoResponse = JsonUtils.jsonToBean(apiResult, ZenTaoResponse.class);
        if (zenTaoResponse!=null&&compareZenTaoResponse(zenTaoResponse)) {
            for (Product product:JsonUtils.jsonToBean(zenTaoResponse.getData(), StoryResponse.class).getStory().getProjects().values()){
                return projectMap.get(product.getId()).getCode();
            }
        }

        throw new RuntimeException("获取任务对应需求的项目信息失败!");
    }
    public static String getTask(String taskId,ZenTaoValues zenTaoValues){
        //zentao/story-view-33224.html
        String apiURL = Constants.URL_PREFIX + "task-view-"+taskId+".json?" + zenTaoValues.getZenTaoSuffix();
        String apiResult = HttpUtil.get(apiURL);
        ZenTaoResponse zenTaoResponse = JsonUtils.jsonToBean(apiResult, ZenTaoResponse.class);
        if (zenTaoResponse!=null&&compareZenTaoResponse(zenTaoResponse)) {
            String data = zenTaoResponse.getData();
            log.info(data);
            int teamIndexOf= data.indexOf("\"team\":",data.indexOf("\"task\":"))+7;
            data=data.substring(0,teamIndexOf)+"{}"+data.substring(teamIndexOf+2);
            System.out.println(data.substring(teamIndexOf));
            System.out.println(data);
            return null;
        }

        throw new RuntimeException("获取任务对应需求的项目信息失败!");
    }
    public static Collection<Bug> getBugsByProjectId(Integer projectId, ZenTaoValues zenTaoValues) {
        /**
         * actionURL: /zentao/project-bug-62-status,id_desc-0-bySearch-myQueryID.html
         *
         */
        Map<String, Object> formData = new HashMap<>();
        formData.put("fieldconfirmed", "ZERO");
        formData.put("fieldproduct", 0);
        formData.put("fieldproject", 0);
        formData.put("fieldseverity", "ZERO");

        formData.put("fieldpri", 0);
        formData.put("fieldmodule", "ZERO");
        formData.put("andOr1", "AND");
        //任务创建时间
        formData.put("field1", "openedDate");
        formData.put("operator1", ">");
        formData.put("value1", zenTaoValues.getStart());


        formData.put("andOr2", "AND");
        formData.put("field2", "openedDate");
        formData.put("operator2", "<");
        formData.put("value2", zenTaoValues.getEnd());
        formData.put("module", "projectBug");
        //project-bug-后面是所对应的项目编号-bySearch-myQueryID
        formData.put("actionURL", "/zentao/project-bug-" + projectId + "-status,id_desc-0-bySearch-myQueryID--1--1-1.json");
        formData.put("groupItems", 3);
        formData.put("formType", "more");
        String apiURL = Constants.URL_PREFIX + "search-buildQuery.json?" + zenTaoValues.getZenTaoSuffix();
        HttpUtil.post(apiURL, formData);
        //project-bug-62-bySearch-myQueryID--2693-2000-1 总数-单页数-第几页
        apiURL=Constants.URL_PREFIX + "project-bug-" + projectId +
                "-status,id_desc-0-bySearch-myQueryID--" + Integer.MAX_VALUE + "-" + Integer.MAX_VALUE + "-1" + ".json?" + zenTaoValues.getZenTaoSuffix();
        String apiResult = HttpUtil.get(apiURL);
        ZenTaoResponse zenTaoResponse = JsonUtils.jsonToBean(apiResult, ZenTaoResponse.class);
        if (zenTaoResponse!=null&&compareZenTaoResponse(zenTaoResponse)) {
            String data = zenTaoResponse.getData();
            int indexOf=data.indexOf("\"bugs\":")+7;

            if(StringUtils.isNotBlank(data)&&!"[".equals(data.substring(indexOf,indexOf+1))){
                //获取所有bug的id和项目id
                //全部数据
                return JsonUtils.jsonToBean(data, BugResponse.class).getBugs().values();
            }

        }
        return Collections.emptyList();
//        throw new RuntimeException("获取项目id为" + projectId + "的任务列表失败!");
    }

    public static Collection<Task> getTasksByProjectId(Integer projectId, ZenTaoValues zenTaoValues) {
        /**
         * actionURL: /zentao/project-task-62-bySearch-myQueryID.html
         */
        Map<String, Object> formData = new HashMap<>();
        formData.put("fieldpri", 0);
        formData.put("fieldmodule", "ZERO");
        formData.put("fieldcancelBy", 0);
        formData.put("andOr1", "AND");
        //任务创建时间
        formData.put("field1", "openedDate");
        formData.put("operator1", ">");
        formData.put("value1", zenTaoValues.getStart());


        formData.put("andOr2", "AND");
        formData.put("field2", "openedDate");
        formData.put("operator2", "<");
        formData.put("value2", zenTaoValues.getEnd());
        formData.put("module", "task");
        //project-task-后面是所对应的项目编号-bySearch-myQueryID
        formData.put("actionURL", "/zentao/project-task-" + projectId + "-bySearch-myQueryID--1--1-1.json");
        formData.put("groupItems", 3);
        formData.put("formType", "more");
        String apiURL = Constants.URL_PREFIX + "search-buildQuery.json?" + zenTaoValues.getZenTaoSuffix();
        HttpUtil.post(apiURL, formData);
        //project-task-62-bySearch-myQueryID--2693-2000-1 总数-单页数-第几页
        apiURL=Constants.URL_PREFIX + "project-task-" + projectId +
                "-bySearch-myQueryID--" + Integer.MAX_VALUE + "-" + Integer.MAX_VALUE + "-1" + ".json?" + zenTaoValues.getZenTaoSuffix();
        String apiResult = HttpUtil.get(apiURL);
        ZenTaoResponse zenTaoResponse = JsonUtils.jsonToBean(apiResult, ZenTaoResponse.class);
        if (zenTaoResponse!=null&&compareZenTaoResponse(zenTaoResponse)) {
            String data = zenTaoResponse.getData();
            int indexOf=data.indexOf("\"tasks\":")+8;
            if(StringUtils.isNotBlank(data)&&!"[".equals(data.substring(indexOf,indexOf+1))){
                FileUtil.writeString(data,System.getProperty("user.dir")+"\\"+"2.txt",StandardCharsets.UTF_8);

//                int teamIndexOf= data.indexOf("\"team\":",data.indexOf("\"tasks\":"))+7;
//                data=data.substring(0,teamIndexOf)+"{}"+data.substring(teamIndexOf+2);
                //全部数据 getAllTaskRemoveTeamConsumed(tasks)
                Collection<Task> tasks = removeChild(JsonUtils.jsonToBean(data, ZenTaoTaskResponse.class).getTasks().values());
                return getAllTaskRemoveTeamConsumed(tasks);
            }

        }
        return Collections.emptyList();
    }
    public static Collection<Task> removeChild(Collection<Task>tasks){
        List<Task> ret=new ArrayList<>(tasks);
        List<Task> children=new ArrayList<>();
        Iterator<Task> iterator = ret.iterator();
        while (iterator.hasNext()){
            Task next = iterator.next();
            if(next.getChildren()!=null&&next.getChildren().size()>0){
                children.addAll(next.getChildren().values());
                iterator.remove();
            }
        }
        ret.addAll(children);
        return ret;
    }
    public static List<Task>  setTaskConsumed(Task task){
        List<Task> teamTask=new ArrayList<>();
        if(CollUtil.isNotEmpty(task.getTeam())){
            for(MemberConsumed memberConsumed:task.getTeam()){
                if(memberConsumed.getConsumed().compareTo(BigDecimal.ZERO)>0){
                    Task task1 = new Task();
                    BeanUtil.copyProperties(task,task1);
                    task1.setFinishedBy(memberConsumed.getAccount());
                    task1.setConsumed(memberConsumed.getConsumed());
                    task1.setTeam(null);
                    teamTask.add(task1);
                }
            }
        }
        return teamTask;
    }
    public static List<Task> getAllTaskRemoveTeamConsumed(Collection<Task> tasks){
        List<Task> allTask=new ArrayList<>();
        Iterator<Task> iterator = tasks.iterator();
        while (iterator.hasNext()){
            Task next = iterator.next();
            List<Task> taskConsumed = setTaskConsumed(next);
            if(CollUtil.isNotEmpty(taskConsumed)){
                iterator.remove();allTask.addAll(taskConsumed);
            }else {
                allTask.add(next);
            }
        }
        return allTask;
    }
    /**
     * 登录之后获取所有的禅道项目
     *
     * @param zenTaoValues
     * @return
     */
    public static List<Project> getAllProjects(ZenTaoValues zenTaoValues) {
        //project-all-all-0-order_desc-0-34-1000-1
        String apiURL = Constants.URL_PREFIX + "project-all-all-0-order_desc-0-"+
                Integer.MAX_VALUE+"-"+Integer.MAX_VALUE+"-1.json?" + zenTaoValues.getZenTaoSuffix();
        String apiResult = HttpUtil.get(apiURL);
        ZenTaoResponse zenTaoResponse = JsonUtils.jsonToBean(apiResult, ZenTaoResponse.class);
        if (zenTaoResponse!=null&&compareZenTaoResponse(zenTaoResponse)) {
            return JsonUtils.jsonToBean(zenTaoResponse.getData(), ProjectResponse.class).getProjectStats();
        }
        throw new RuntimeException("获取所有项目失败!");
    }

    /**
     * 已经做过登录操作
     * 获取本部门的所有用户
     *
     * @param zenTaoValues
     * @return
     */
    public static List<User> getUsersByDept(ZenTaoValues zenTaoValues) {
        //company-browse-23-bydept-id-41-20-2.html
        String apiURL = Constants.URL_PREFIX + "company-browse-" + zenTaoValues.getDept() + "-bydept-id-" + Integer.MAX_VALUE + "" + "-" + Integer.MAX_VALUE + "-1.json?" + zenTaoValues.getZenTaoSuffix();
        String apiResult = HttpUtil.get(apiURL);
        ZenTaoResponse zenTaoResponse = JsonUtils.jsonToBean(apiResult, ZenTaoResponse.class);
        if (zenTaoResponse!=null&&compareZenTaoResponse(zenTaoResponse)) {
            DeptUserResponse deptUserResponse = JsonUtils.jsonToBean(zenTaoResponse.getData(), DeptUserResponse.class);
            //pageTotal==1
            if ((int) deptUserResponse.getPager().get("pageTotal") == 1) {
                return deptUserResponse.getUsers();
            }
        }
        return null;
    }


    /**
     * 登录禅道
     *
     * @param account
     * @param password
     * @param zenTaoSuffix
     * @return true为登录禅道成功
     */
    public static boolean zenTaoLogin(String account, String password, String zenTaoSuffix) {
        Map<String, Object> formData = new HashMap<>();
        String loginUrl = Constants.URL_PREFIX + "user-login.json?" + zenTaoSuffix;
        formData.put("account", account);
        formData.put("password", password);
        String response = HttpUtil.post(loginUrl, formData);
        ZenTaoResponse zenTaoResponse = JsonUtils.jsonToBean(response, ZenTaoResponse.class);
        return Constants.SUCCESS_STATUS.equals(zenTaoResponse.getStatus());

    }

    /**
     * String account,String password
     * 获取sessionID
     * zentaosid=ifmo18iki6s5816ni11lcck262
     *
     * @return
     */
    public static String getZenTaoSuffix() {
        String result = HttpUtil.get(Constants.URL_PREFIX + "api-getsessionid.json");
        //1.获取sessionID
        ZenTaoResponse zenTaoResponse = JsonUtils.jsonToBean(result, ZenTaoResponse.class);
        //比较响应数据是否正确
        if (zenTaoResponse!=null&&compareZenTaoResponse(zenTaoResponse)) {
            ZenTaoResponseData data = JsonUtils.jsonToBean(zenTaoResponse.getData(), ZenTaoResponseData.class);
            if (Objects.nonNull(data) && StringUtils.isNotBlank(data.getSessionID())) {
                return data.getSessionName() + "=" + data.getSessionID();
            }
        }
        throw new RuntimeException("获取sessionID异常!");
    }

    /**
     * 退出禅道
     *
     * @param zenTaoSuffix getZenTaoSuffix中获取的sessionID后缀
     * @return true为成功退出
     */
    public static boolean zenTaoLogout(String zenTaoSuffix) {
        String response = HttpUtil.get(Constants.URL_PREFIX + "user-logout.json?" + zenTaoSuffix);
        ZenTaoResponse zenTaoResponse = JsonUtils.jsonToBean(response, ZenTaoResponse.class);
        return Constants.SUCCESS_STATUS.equals(zenTaoResponse.getStatus());
    }

    public static boolean compareZenTaoResponse(ZenTaoResponse zenTaoResponse) {
        return Constants.SUCCESS_STATUS.equals(zenTaoResponse.getStatus()) && StringUtils.isNotBlank(zenTaoResponse.getData()) && compareMD5(zenTaoResponse.getMd5(), zenTaoResponse.getData());
    }

    /**
     * 比较md5密文和data加密之后是否一致
     *
     * @param md5Word md5密文
     * @param data    data数据
     * @return
     */
    public static boolean compareMD5(String md5Word, String data) {
        MD5 md5 = SecureUtil.md5();
        byte[] digest = md5.digest(data);
        //MD5加密转换成32进制密文
        StringBuilder result = new StringBuilder();
        for (byte dig : digest) {
            int val = ((int) dig) & 0xff;
            if (val < 16) {
                result.append("0");
            }
            result.append(Integer.toHexString(val));
        }
        return md5Word.equals(result.toString());
    }
}
